package service

import (
	"FlowMaster/logger"
	"FlowMaster/model"
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"time"
)

// 上传客流统计接口服务

var lg = logger.Get()

func getAccessToken(baseURL, appkey, appsecret string) error {
	params := url.Values{
		"appkey":    {appkey},
		"appsecret": {appsecret},
	}
	lg.Debug("CheckAccessToken params is ", params)
	tokenURL := baseURL + "/api/book/get_token"
	resp, err := http.Get(tokenURL + "?" + params.Encode())
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	contentType := resp.Header.Get("Content-Type")
	lg.Debug("contentType is ", contentType)
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	lg.Debug("body is", string(body))
	var tokenResponse model.TokenResponse
	err = json.Unmarshal(body, &tokenResponse)
	if err != nil {
		lg.Error("Error unmarshalling JSON:", err)
		return err
	}
	tokenData := tokenResponse.TokenData
	lg.Debug("body tokenData is ", tokenData)
	lg.Debug("tokenResponse  is ", tokenResponse)
	err = SetTokenToEnv(tokenData.Access_token, tokenData.Token_type, strconv.Itoa(int(tokenData.Expires_in)))
	if err != nil {
		return err
	}
	return nil
}

func getAccessTokenFromEnv() (*model.TokenData, error) {

	tokenData, err := GetTokenFromEnv()
	if err != nil {
		return &model.TokenData{}, err
	}
	return tokenData, nil

}

func CheckAccessToken(baseURL, appkey, appsecret string) (string, error) {
	tokenURL := baseURL + "/api/book/get_token"
	tokenData, err := getAccessTokenFromEnv()
	lg.Info("getAccessTokenFromEnv tokenData is", tokenData)
	if err != nil {
		_ = getAccessToken(tokenURL, appkey, appsecret)
		tokenDataR, _ := getAccessTokenFromEnv()
		lg.Info("getAccessTokenFromEnv tokenDataR is", tokenDataR)
		return tokenDataR.Access_token, nil
	}

	// expiresIn, err := time.Parse(time.RFC3339, tokenData.Expires_in)
	expiresIn := time.Unix(tokenData.Expires_in, 0).UTC()

	// if err != nil {
	// 	return "", err
	// }

	if time.Now().After(expiresIn) {
		// access_token 已过期，重新获取
		err := getAccessToken(tokenURL, appkey, appsecret)
		if err != nil {
			return "", err
		}
		tokenDataR, _ := getAccessTokenFromEnv()
		lg.Info(" access_token 已过期，重新获取getAccessTokenFromEnv tokenDataR is", tokenDataR)

		return tokenDataR.Access_token, nil
	}

	return tokenData.Access_token, nil
}

func UploadData(baseURL string, accessToken string, m *model.UploadDataRequest) (*model.UploadDataResponse, error) {
	apiURL := baseURL + "/api/book/uploadData"
	data := url.Values{}
	data.Set("scenic_id", m.Scenic_id)
	data.Set("scenic_status", strconv.Itoa(m.Scenic_status))
	data.Set("notice", m.Notice)
	data.Set("total_tourists", strconv.Itoa(m.Total_tourists))
	data.Set("out_tourists", strconv.Itoa(m.Out_tourists))
	data.Set("realtime_tourists", strconv.Itoa(m.Realtime_tourists))
	data.Set("request_time", strconv.Itoa(int(m.Request_time)))
	// 创建 book_list 数组
	bookList := url.Values{}

	bookList.Set("label", m.Book_list[0].Label)
	bookList.Set("start_time", strconv.Itoa(int(m.Book_list[0].StartTime)))
	bookList.Set("end_time", strconv.Itoa(int(m.Book_list[0].EndTime)))
	bookList.Set("book_num", strconv.Itoa(m.Book_list[0].Book_num))
	bookList.Set("remain_num", strconv.Itoa(m.Book_list[0].Remain_num))
	// 将 book_list 添加到主数据结构中

	data.Add("book_list", bookList.Encode())

	// 使用bytes.NewBufferString创建io.Reader
	reqBody := bytes.NewBufferString(data.Encode())
	lg.Debug("UploadData reqBody", reqBody)
	// 创建HTTP请求
	req, err := http.NewRequest("POST", apiURL, reqBody)
	if err != nil {
		lg.Debug("Error creating HTTP request:", err)
		return nil, err
	}
	lg.Info("Bearer ", accessToken)
	// 设置Authorization头
	req.Header.Set("Authorization", "Bearer "+accessToken)
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	// 创建HTTP客户端
	client := &http.Client{}
	// 发送HTTP请求
	resp, err := client.Do(req)
	if err != nil {
		lg.Debug("Error sending HTTP request:", err)
		return nil, err
	}
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {
			return
		}
	}(resp.Body)

	// 读取响应体
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		lg.Debug("Error reading HTTP response body:", err)
		return nil, err
	}

	// 解析响应体为UploadDataResponse
	var uploadDataResponse model.UploadDataResponse
	err = json.Unmarshal(body, &uploadDataResponse)
	if err != nil {
		lg.Debug("Error unmarshalling JSON:", err)
		return nil, err
	}

	return &uploadDataResponse, nil
}

func SearchScenicBykeyword(baseURL string, q string) (*model.ScenicResponse, error) {
	apiURL := baseURL + "/api/book/search_scenic_bykeyword"
	params := url.Values{}

	params.Add("q", q)

	url := fmt.Sprintf("%s?%s", apiURL, params.Encode())

	resp, err := http.Get(url)
	if err != nil {
		lg.Debug("Error SearchScenicBykeyword HTTP request:", err)
		return nil, err
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		lg.Debug("Error reading SearchScenicBykeyword response body:", err)
		return nil, err
	}

	var scenicResp model.ScenicResponse
	err = json.Unmarshal(body, &scenicResp)
	if err != nil {
		lg.Debug("Error  SearchScenicBykeyword unmarshalling JSON:", err)
		return nil, err
	}

	for _, data := range scenicResp.Data {
		lg.Debugf("Scenic Name: %s\nAddress: %s\nCity: %s\n\n", data.NameCN, data.Address, data.CityName)
	}
	return &scenicResp, err
}

func GetScenicID(baseURL string, q string) (string, error) {
	scenicId, err := GetScenicIDFromEnv()
	if err != nil {
		scenicResp, err := SearchScenicBykeyword(baseURL, q)
		if err != nil {
			return "", err
		}
		scenicId := scenicResp.Data[0].ScenicID
		_ = SetScenicID(scenicId)
		return scenicId, nil
	}
	return scenicId, nil

}
